# -*- coding: utf-8 -*-
# @Time     : 2020/8/13 3:40 下午
# @Author   : huangxiong
# @FileName : output_portfolio_info.py
# @Comment  : 计算组合持仓、资产配置、子基金收益贡献
# @Software : PyCharm
import pandas as pd

from quant_researcher.quant.project_tool.db_operator import db_conn
from quant_researcher.quant.project_tool import time_tool
from quant_researcher.quant.project_tool.logger.my_logger import LOG
from quant_researcher.quant.project_tool.db_operator.my_excel import df_2_excel
from quant_researcher.quant.datasource_fetch.portfolio_api import portfolio_tool
from quant_researcher.quant.datasource_fetch.fund_api import fund_classification
from quant_researcher.quant.performance_attribution.fof_related import deprecating_ret_decomposition
from quant_researcher.quant.performance_attribution.core_functions.holding_analysis import holding_analysis
from quant_researcher.quant.datasource_fetch.index_api.index_info import get_sw_industry_name

FUND_NAV_TABLE = 'mf_nv_netvalue'


def output_portfolio_holding(portfolio_id, date=None):
    """
    得到组合在某一天的持仓情况

    :param portfolio_id: 组合ID
    :param date: 日期，格式形如"20200810"，默认为每月最后一天
    :return: pd.DataFrame，列包括[基金代码，基金简称，基金类型，成本占比，市值占比，市值，最新净值]
    """
    if date is None:
        date = time_tool.get_the_end_of_last_month(time_tool.get_today(marker='without_n_dash'))

    df = portfolio_tool.get_portfolio_hold_related_info(portfolio_id, date)
    if df is None:
        LOG.error(f"没有找到组合{portfolio_id}在{date}之前的信息")
        return
    latest_date = df['backup_date'].iloc[0]
    df = df.rename(columns={'fund_balance': 'value'})
    df['cost_balance'] = df['total_qty'] * df['cost_price']
    df['cost_pct'] = df['cost_balance'] / df['cost_balance'].sum() * 100
    df['value_pct'] = df['value'] / df['value'].sum() * 100

    cls_df = fund_classification.get_fund_cls_info(
        category_rank=1, select=['fund_code', 'category_code']
    )
    cls_name_df = fund_classification.get_cls_name(category_rank=1)

    df = df.merge(cls_df, how='left', on='fund_code')
    df = df.merge(cls_name_df, how='left', on='category_code')

    conn_base = db_conn.get_basic_data_conn()
    nav_df = pd.read_sql(f"select fund_code, nav "
                         f"from {FUND_NAV_TABLE} "
                         f"where end_date = '{latest_date}' ", conn_base)
    df = df.merge(nav_df, how='left', on='fund_code')

    df = df[['fund_code', 'fund_name', 'category_name',
             'cost_pct', 'value_pct', 'value', 'nav']]

    df = df.rename(columns={'fund_code': '基金代码', 'fund_name': '基金简称', 'category_name': '基金类型',
                            'cost_pct': '成本占比(%)', 'value_pct': '市值占比(%)', 'value': '市值(元)', 'nav': '最新净值'})

    df_2_excel(df, file_name=f'{portfolio_id}在{date}持仓结果')

    conn_base.close()
    return df


def output_fund_ret(portfolio_id, calc_month):
    df = deprecating_ret_decomposition.get_fund_ret(portfolio_id, calc_month)
    if df is None:
        return
    df_2_excel(df, file_name=f'{portfolio_id}子基金{calc_month}收益率情况')


def output_fund_ret_attrib(portfolio_id, calc_month):
    df = deprecating_ret_decomposition.get_fund_ret_attrib_4_report(portfolio_id, calc_month)
    if df is None:
        return
    df = df.rename(columns={'fund_code': '基金代码', 'fund_sname': '基金简称',
                            'fund_weight': '权重占比', 'ret_attrib': '收益率贡献'})
    df_2_excel(df, file_name=f'{portfolio_id}在{calc_month}基金收益贡献率结果')


def output_portfolio_asset_allocation(portfolio_id, calc_date=None):
    df = holding_analysis.get_portfolio_asset_allocation(portfolio_id, calc_date)
    if df is None:
        return
    df_2_excel(df, file_name=f'{portfolio_id}在{calc_date}的大类资产配置结果')


def output_portfolio_industry_allocation(portfolio_id, calc_date=None):
    df = holding_analysis.get_portfolio_industry_allocation(portfolio_id, calc_date)
    if df is None:
        return
    industry_name = get_sw_industry_name()
    df = df.merge(industry_name, how='left', on='industry_code')
    df_2_excel(df, file_name=f'{portfolio_id}在{calc_date}的股票申万行业配置结果')


if __name__ == "__main__":
    pass
